// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GREEDY_PALETTIZATION_INTERLACE_BITS_INL_H_
#define GREEDY_PALETTIZATION_INTERLACE_BITS_INL_H_

#include <stdint.h>

namespace greedy_palettization {

// Given 4 bytes b3, b2, b1, b0 the output is the bit-stream
// b3[7] b2[7] b1[7] b0[7] b3[6] b2[6] b1[6] b0[6] ... b3[0] b2[0] b1[0] b0[0]
inline uint32_t Interlace4Bytes(uint8_t b3,
                              uint8_t b2,
                              uint8_t b1,
                              uint8_t b0) {
  static const uint32_t expand_bits[256] = {
    0x00000000, 0x00000001, 0x00000010, 0x00000011,
    0x00000100, 0x00000101, 0x00000110, 0x00000111,
    0x00001000, 0x00001001, 0x00001010, 0x00001011,
    0x00001100, 0x00001101, 0x00001110, 0x00001111,
    0x00010000, 0x00010001, 0x00010010, 0x00010011,
    0x00010100, 0x00010101, 0x00010110, 0x00010111,
    0x00011000, 0x00011001, 0x00011010, 0x00011011,
    0x00011100, 0x00011101, 0x00011110, 0x00011111,
    0x00100000, 0x00100001, 0x00100010, 0x00100011,
    0x00100100, 0x00100101, 0x00100110, 0x00100111,
    0x00101000, 0x00101001, 0x00101010, 0x00101011,
    0x00101100, 0x00101101, 0x00101110, 0x00101111,
    0x00110000, 0x00110001, 0x00110010, 0x00110011,
    0x00110100, 0x00110101, 0x00110110, 0x00110111,
    0x00111000, 0x00111001, 0x00111010, 0x00111011,
    0x00111100, 0x00111101, 0x00111110, 0x00111111,
    0x01000000, 0x01000001, 0x01000010, 0x01000011,
    0x01000100, 0x01000101, 0x01000110, 0x01000111,
    0x01001000, 0x01001001, 0x01001010, 0x01001011,
    0x01001100, 0x01001101, 0x01001110, 0x01001111,
    0x01010000, 0x01010001, 0x01010010, 0x01010011,
    0x01010100, 0x01010101, 0x01010110, 0x01010111,
    0x01011000, 0x01011001, 0x01011010, 0x01011011,
    0x01011100, 0x01011101, 0x01011110, 0x01011111,
    0x01100000, 0x01100001, 0x01100010, 0x01100011,
    0x01100100, 0x01100101, 0x01100110, 0x01100111,
    0x01101000, 0x01101001, 0x01101010, 0x01101011,
    0x01101100, 0x01101101, 0x01101110, 0x01101111,
    0x01110000, 0x01110001, 0x01110010, 0x01110011,
    0x01110100, 0x01110101, 0x01110110, 0x01110111,
    0x01111000, 0x01111001, 0x01111010, 0x01111011,
    0x01111100, 0x01111101, 0x01111110, 0x01111111,
    0x10000000, 0x10000001, 0x10000010, 0x10000011,
    0x10000100, 0x10000101, 0x10000110, 0x10000111,
    0x10001000, 0x10001001, 0x10001010, 0x10001011,
    0x10001100, 0x10001101, 0x10001110, 0x10001111,
    0x10010000, 0x10010001, 0x10010010, 0x10010011,
    0x10010100, 0x10010101, 0x10010110, 0x10010111,
    0x10011000, 0x10011001, 0x10011010, 0x10011011,
    0x10011100, 0x10011101, 0x10011110, 0x10011111,
    0x10100000, 0x10100001, 0x10100010, 0x10100011,
    0x10100100, 0x10100101, 0x10100110, 0x10100111,
    0x10101000, 0x10101001, 0x10101010, 0x10101011,
    0x10101100, 0x10101101, 0x10101110, 0x10101111,
    0x10110000, 0x10110001, 0x10110010, 0x10110011,
    0x10110100, 0x10110101, 0x10110110, 0x10110111,
    0x10111000, 0x10111001, 0x10111010, 0x10111011,
    0x10111100, 0x10111101, 0x10111110, 0x10111111,
    0x11000000, 0x11000001, 0x11000010, 0x11000011,
    0x11000100, 0x11000101, 0x11000110, 0x11000111,
    0x11001000, 0x11001001, 0x11001010, 0x11001011,
    0x11001100, 0x11001101, 0x11001110, 0x11001111,
    0x11010000, 0x11010001, 0x11010010, 0x11010011,
    0x11010100, 0x11010101, 0x11010110, 0x11010111,
    0x11011000, 0x11011001, 0x11011010, 0x11011011,
    0x11011100, 0x11011101, 0x11011110, 0x11011111,
    0x11100000, 0x11100001, 0x11100010, 0x11100011,
    0x11100100, 0x11100101, 0x11100110, 0x11100111,
    0x11101000, 0x11101001, 0x11101010, 0x11101011,
    0x11101100, 0x11101101, 0x11101110, 0x11101111,
    0x11110000, 0x11110001, 0x11110010, 0x11110011,
    0x11110100, 0x11110101, 0x11110110, 0x11110111,
    0x11111000, 0x11111001, 0x11111010, 0x11111011,
    0x11111100, 0x11111101, 0x11111110, 0x11111111,
  };
  return ((expand_bits[b3] << 3) |
          (expand_bits[b2] << 2) |
          (expand_bits[b1] << 1) |
          (expand_bits[b0] << 0));
}

}  // namespace greedy_palettization

#endif  // GREEDY_PALETTIZATION_INTERLACE_BITS_INL_H_
